-- bat_damage
-- create by xinj
-- 蝙蝠镖伤害

return {
    apply = function(source, target, skillId, round, para, extra)
        local force = para[1];
        local level = 0;

        -- 蝙蝠专属加强效果
        local prop = PropM.combine(source, "bat", 1);
        level = PropM.apply(prop, level);
        if prop[3] > 0 then
            -- 触发特技发动事件
            EventMgr.fire(event.SPECIAL_SKILL_TRIGGER, { propId = prop[1] });
        end

        if level >= 3 then
            force = force + 100;
        end

        -- 目标范围
        local ret = { target };

        -- 5级全屏效果
        if level >= 5 then
            -- 遍历怪物周围所有已开且存活的怪
            local pos = target.dbase:query("pos");
            if not pos then
                pos = target:getOwner();
            end

            for p = 1, DUNGEON_WIDTH * DUNGEON_HEIGHT do
                local grid = DungeonM.getGridByPos(p);

                -- 翻开且存活的怪物
                if  grid:isOpened() and
                    grid:isMonster() and
                    grid.monster ~= target and
                    not grid.monster:isDead() then
                    table.insert(ret, grid.monster);
                end
            end
        end

        local damage = force;

        local props;
        local addon;
        local args;

        local final_damage;
        local max = damage;
        for _, monster in pairs(ret) do
            addon = 0;
            final_damage = damage;
            args  = {["value"] = final_damage, ["class_id"] = extra.propertyId,}

            -- 对远程怪加成
            if level >= 1 and monster:isRemoteMonster() then
                final_damage = math.modf(final_damage * 15 / 10);
            end

            -- 对亡灵加成
            if level >= 2 and monster.style == MONSTER_STYLE_UNDEAD then
                final_damage = math.modf(final_damage * 15 / 10);
            end

            -- 概率造成额外的固定伤害
            props = PropM.fetchProps(source, "prob_fixed_damage");
            for _, prop in ipairs(props) do
                addon = addon + PropM.trigger(source, prop[1], prop[2], args);
            end

            final_damage = final_damage + addon;

            -- 取出最大伤害
            max = math.max(max, final_damage);

            -- 道具修正伤害
            local classId = extra["propertyId"];
            if type(classId) == "number" then
                final_damage = PropertyM.calcFinalDamage(source, monster, classId, final_damage);
            end

            -- 增加命中动作
            if SkillM.getSequence(monster) == nil then
                SkillM.getSequenceList()[monster] = CastSequence.create(source, monster, skillId);
            end

            SkillM.getSequence(monster):hit(source, monster, skillId);
            -- 受创
            CombatM.receiveDamage(source, monster, final_damage, skillId, extra);
        end

        -- 吸血效果
        if level >= 4 and FormulaM.invoke("IS_LIVING_MONSTER", target) then
            local recover = math.max(1, math.modf(max / 2));
            BonusM.doBonus({ 2, "hp", recover, }, "bat absorb");
            EventMgr.fire(event.HP_VAMPIRE, recover);
        end

        -- 如果受攻击对象是怪物，且由道具触发技能，抛出投掷类攻击事件
        if target.type == OBJECT_TYPE_MONSTER and para[2] > 0 then
            if #ret == 1 then
                EventMgr.fire(event.PROPERTY_ATTACK, { ["classId"] = para[2], ["target"] = target, ["source"] = source});
            else
                table.removeItem(ret, target);
                EventMgr.fire(event.PROPERTY_ATTACK, { ["classId"] = para[2], ["target"] = target, ["source"] = source, ["moreTarget"] = ret});
            end
        end

        -- 作用目标
        return ret;
    end,

    parse = function(desc)
        local arr = string.explode(desc, ",");
        if (#arr >= 1) then
            return { tonumber(arr[1]), tonumber(arr[2]) or -1,};
        end
    end,

    -- 解析技能描述
    parseDesc = function(source, skillId, desc, para)
        -- 无需技能描述
        return desc;
    end,
};
